home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / dev / misc / flex_2_4_7.lha / flex-2.4.7gen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-22  |  32.7 KB  |  1,468 lines

  1. /* gen - actual generation (writing) of flex scanners */
  2.  
  3. /*-
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant
  11.  * to contract no. DE-AC03-76SF00098 between the United States
  12.  * Department of Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided
  15.  * that: (1) source distributions retain this entire copyright notice and
  16.  * comment, and (2) distributions including binaries display the following
  17.  * acknowledgement:  ``This product includes software developed by the
  18.  * University of California, Berkeley and its contributors'' in the
  19.  * documentation or other materials provided with the distribution and in
  20.  * all advertising materials mentioning features or use of this software.
  21.  * Neither the name of the University nor the names of its contributors may
  22.  * be used to endorse or promote products derived from this software without
  23.  * specific prior written permission.
  24.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27.  */
  28.  
  29. /* $Header: /home/daffy/u0/vern/flex/flex-2.4.7/RCS/gen.c,v 1.3 94/08/03 11:37:45 vern Exp $ */
  30.  
  31. #include "flexdef.h"
  32.  
  33.  
  34. /* declare functions that have forward references */
  35.  
  36. void gen_next_state PROTO((int));
  37. void genecs PROTO((void));
  38. void indent_put2s PROTO((char [], char []));
  39. void indent_puts PROTO((char []));
  40. void do_indent PROTO((void));
  41. void gen_backing_up PROTO((void));
  42. void gen_bu_action PROTO((void));
  43. void genctbl PROTO((void));
  44. void gen_find_action PROTO((void));
  45. void genftbl PROTO((void));
  46. void gen_next_compressed_state PROTO((char *char_map));
  47. void gen_next_match PROTO((void));
  48. void gen_NUL_trans PROTO((void));
  49. void gen_start_state PROTO((void));
  50. void gentabs PROTO((void));
  51.  
  52.  
  53. static int indent_level = 0; /* each level is 8 spaces */
  54.  
  55. #define indent_up() (++indent_level)
  56. #define indent_down() (--indent_level)
  57. #define set_indent(indent_val) indent_level = indent_val
  58.  
  59. /* Almost everything is done in terms of arrays starting at 1, so provide
  60.  * a null entry for the zero element of all C arrays.  (The exception
  61.  * to this is that the fast table representation generally uses the
  62.  * 0 elements of its arrays, too.)
  63.  */
  64. static char C_int_decl[] = "static const int %s[%d] =\n    {   0,\n";
  65. static char C_short_decl[] = "static const short int %s[%d] =\n    {   0,\n";
  66. static char C_long_decl[] = "static const long int %s[%d] =\n    {   0,\n";
  67. static char C_state_decl[] =
  68.     "static const yy_state_type %s[%d] =\n    {   0,\n";
  69.  
  70.  
  71. /* Indent to the current level. */
  72.  
  73. void do_indent()
  74.     {
  75.     register int i = indent_level * 8;
  76.  
  77.     while ( i >= 8 )
  78.         {
  79.         putchar( '\t' );
  80.         i -= 8;
  81.         }
  82.  
  83.     while ( i > 0 )
  84.         {
  85.         putchar( ' ' );
  86.         --i;
  87.         }
  88.     }
  89.  
  90.  
  91. /* Generate the code to keep backing-up information. */
  92.  
  93. void gen_backing_up()
  94.     {
  95.     if ( reject || num_backing_up == 0 )
  96.         return;
  97.  
  98.     if ( fullspd )
  99.         indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  100.     else
  101.         indent_puts( "if ( yy_accept[yy_current_state] )" );
  102.  
  103.     indent_up();
  104.     indent_puts( "{" );
  105.     indent_puts( "yy_last_accepting_state = yy_current_state;" );
  106.     indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  107.     indent_puts( "}" );
  108.     indent_down();
  109.     }
  110.  
  111.  
  112. /* Generate the code to perform the backing up. */
  113.  
  114. void gen_bu_action()
  115.     {
  116.     if ( reject || num_backing_up == 0 )
  117.         return;
  118.  
  119.     set_indent( 3 );
  120.  
  121.     indent_puts( "case 0: /* must back up */" );
  122.     indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
  123.     indent_puts( "*yy_cp = yy_hold_char;" );
  124.  
  125.     if ( fullspd || fulltbl )
  126.         indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
  127.     else
  128.         /* Backing-up info for compressed tables is taken \after/
  129.          * yy_cp has been incremented for the next state.
  130.          */
  131.         indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  132.  
  133.     indent_puts( "yy_current_state = yy_last_accepting_state;" );
  134.     indent_puts( "goto yy_find_action;" );
  135.     putchar( '\n' );
  136.  
  137.     set_indent( 0 );
  138.     }
  139.  
  140.  
  141. /* genctbl - generates full speed compressed transition table */
  142.  
  143. void genctbl()
  144.     {
  145.     register int i;
  146.     int end_of_buffer_action = num_rules + 1;
  147.  
  148.     /* Table of verify for transition and offset to next state. */
  149.     printf( "static const struct yy_trans_info yy_transition[%d] =\n",
  150.         tblend + numecs + 1 );
  151.     printf( "    {\n" );
  152.  
  153.     /* We want the transition to be represented as the offset to the
  154.      * next state, not the actual state number, which is what it currently
  155.      * is.  The offset is base[nxt[i]] - (base of current state)].  That's
  156.      * just the difference between the starting points of the two involved
  157.      * states (to - from).
  158.      *
  159.      * First, though, we need to find some way to put in our end-of-buffer
  160.      * flags and states.  We do this by making a state with absolutely no
  161.      * transitions.  We put it at the end of the table.
  162.      */
  163.  
  164.     /* We need to have room in nxt/chk for two more slots: One for the
  165.      * action and one for the end-of-buffer transition.  We now *assume*
  166.      * that we're guaranteed the only character we'll try to index this
  167.      * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
  168.      * there's room for jam entries for other characters.
  169.      */
  170.  
  171.     while ( tblend + 2 >= current_max_xpairs )
  172.         expand_nxt_chk();
  173.  
  174.     while ( lastdfa + 1 >= current_max_dfas )
  175.         increase_max_dfas();
  176.  
  177.     base[lastdfa + 1] = tblend + 2;
  178.     nxt[tblend + 1] = end_of_buffer_action;
  179.     chk[tblend + 1] = numecs + 1;
  180.     chk[tblend + 2] = 1; /* anything but EOB */
  181.  
  182.     /* So that "make test" won't show arb. differences. */
  183.     nxt[tblend + 2] = 0;
  184.     dfaacc[0].dfaacc_state = 0;
  185.  
  186.     /* Make sure every state has an end-of-buffer transition and an
  187.      * action #.
  188.      */
  189.     for ( i = 0; i <= lastdfa; ++i )
  190.         {
  191.         int anum = dfaacc[i].dfaacc_state;
  192.         int offset = base[i];
  193.  
  194.         chk[offset] = EOB_POSITION;
  195.         chk[offset - 1] = ACTION_POSITION;
  196.         nxt[offset - 1] = anum;    /* action number */
  197.         }
  198.  
  199.     for ( i = 0; i <= tblend; ++i )
  200.         {
  201.         if ( chk[i] == EOB_POSITION )
  202.             transition_struct_out( 0, base[lastdfa + 1] - i );
  203.  
  204.         else if ( chk[i] == ACTION_POSITION )
  205.             transition_struct_out( 0, nxt[i] );
  206.  
  207.         else if ( chk[i] > numecs || chk[i] == 0 )
  208.             transition_struct_out( 0, 0 );    /* unused slot */
  209.  
  210.         else    /* verify, transition */
  211.             transition_struct_out( chk[i],
  212.                         base[nxt[i]] - (i - chk[i]) );
  213.         }
  214.  
  215.  
  216.     /* Here's the final, end-of-buffer state. */
  217.     transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
  218.     transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
  219.  
  220.     printf( "    };\n" );
  221.     printf( "\n" );
  222.  
  223.     /* Table of pointers to start states. */
  224.     printf(
  225.     "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
  226.         lastsc * 2 + 1 );
  227.     printf( "    {\n" );    /* } so vi doesn't get confused */
  228.  
  229.     for ( i = 0; i <= lastsc * 2; ++i )
  230.         printf( "    &yy_transition[%d],\n", base[i] );
  231.  
  232.     dataend();
  233.  
  234.     if ( useecs )
  235.         genecs();
  236.     }
  237.  
  238.  
  239. /* Generate equivalence-class tables. */
  240.  
  241. void genecs()
  242.     {
  243.     Char clower();
  244.     register int i, j;
  245.     int numrows;
  246.  
  247.     printf( C_int_decl, "yy_ec", csize );
  248.  
  249.     for ( i = 1; i < csize; ++i )
  250.         {
  251.         if ( caseins && (i >= 'A') && (i <= 'Z') )
  252.             ecgroup[i] = ecgroup[clower( i )];
  253.  
  254.         ecgroup[i] = ABS( ecgroup[i] );
  255.         mkdata( ecgroup[i] );
  256.         }
  257.  
  258.     dataend();
  259.  
  260.     if ( trace )
  261.         {
  262.         fputs( "\n\nEquivalence Classes:\n\n", stderr );
  263.  
  264.         numrows = csize / 8;
  265.  
  266.         for ( j = 0; j < numrows; ++j )
  267.             {
  268.             for ( i = j; i < csize; i = i + numrows )
  269.                 {
  270.                 fprintf( stderr, "%4s = %-2d",
  271.                     readable_form( i ), ecgroup[i] );
  272.  
  273.                 putc( ' ', stderr );
  274.                 }
  275.  
  276.             putc( '\n', stderr );
  277.             }
  278.         }
  279.     }
  280.  
  281.  
  282. /* Generate the code to find the action number. */
  283.  
  284. void gen_find_action()
  285.     {
  286.     if ( fullspd )
  287.         indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );
  288.  
  289.     else if ( fulltbl )
  290.         indent_puts( "yy_act = yy_accept[yy_current_state];" );
  291.  
  292.     else if ( reject )
  293.         {
  294.         indent_puts( "yy_current_state = *--yy_state_ptr;" );
  295.         indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  296.  
  297.         puts(
  298.         "find_rule: /* we branch to this label when backing up */" );
  299.  
  300.         indent_puts(
  301.         "for ( ; ; ) /* until we find what rule we matched */" );
  302.  
  303.         indent_up();
  304.  
  305.         indent_puts( "{" );
  306.  
  307.         indent_puts(
  308.         "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
  309.         indent_up();
  310.         indent_puts( "{" );
  311.         indent_puts( "yy_act = yy_acclist[yy_lp];" );
  312.  
  313.         if ( variable_trailing_context_rules )
  314.             {
  315.             indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
  316.             indent_puts( "     yy_looking_for_trail_begin )" );
  317.             indent_up();
  318.             indent_puts( "{" );
  319.  
  320.             indent_puts(
  321.                 "if ( yy_act == yy_looking_for_trail_begin )" );
  322.             indent_up();
  323.             indent_puts( "{" );
  324.             indent_puts( "yy_looking_for_trail_begin = 0;" );
  325.             indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
  326.             indent_puts( "break;" );
  327.             indent_puts( "}" );
  328.             indent_down();
  329.  
  330.             indent_puts( "}" );
  331.             indent_down();
  332.  
  333.             indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
  334.             indent_up();
  335.             indent_puts( "{" );
  336.             indent_puts(
  337.         "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
  338.             indent_puts(
  339.         "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
  340.  
  341.             if ( real_reject )
  342.                 {
  343.                 /* Remember matched text in case we back up
  344.                  * due to REJECT.
  345.                  */
  346.                 indent_puts( "yy_full_match = yy_cp;" );
  347.                 indent_puts( "yy_full_state = yy_state_ptr;" );
  348.                 indent_puts( "yy_full_lp = yy_lp;" );
  349.                 }
  350.  
  351.             indent_puts( "}" );
  352.             indent_down();
  353.  
  354.             indent_puts( "else" );
  355.             indent_up();
  356.             indent_puts( "{" );
  357.             indent_puts( "yy_full_match = yy_cp;" );
  358.             indent_puts( "yy_full_state = yy_state_ptr;" );
  359.             indent_puts( "yy_full_lp = yy_lp;" );
  360.             indent_puts( "break;" );
  361.             indent_puts( "}" );
  362.             indent_down();
  363.  
  364.             indent_puts( "++yy_lp;" );
  365.             indent_puts( "goto find_rule;" );
  366.             }
  367.  
  368.         else
  369.         {
  370.         /* Remember matched text in case we back up due to trailing
  371.          * context plus REJECT.
  372.          */
  373.         indent_up();
  374.         indent_puts( "{" );
  375.         indent_puts( "yy_full_match = yy_cp;" );
  376.         indent_puts( "break;" );
  377.         indent_puts( "}" );
  378.         indent_down();
  379.         }
  380.  
  381.         indent_puts( "}" );
  382.         indent_down();
  383.  
  384.         indent_puts( "--yy_cp;" );
  385.  
  386.         /* We could consolidate the following two lines with those at
  387.          * the beginning, but at the cost of complaints that we're
  388.          * branching inside a loop.
  389.          */
  390.         indent_puts( "yy_current_state = *--yy_state_ptr;" );
  391.         indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  392.  
  393.         indent_puts( "}" );
  394.  
  395.         indent_down();
  396.         }
  397.  
  398.     else
  399.         /* compressed */
  400.         indent_puts( "yy_act = yy_accept[yy_current_state];" );
  401.     }
  402.  
  403.  
  404. /* genftbl - generates full transition table */
  405.  
  406. void genftbl()
  407.     {
  408.     register int i;
  409.     int end_of_buffer_action = num_rules + 1;
  410.  
  411.     printf( long_align ? C_long_decl : C_short_decl,
  412.         "yy_accept", lastdfa + 1 );
  413.  
  414.     dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  415.  
  416.     for ( i = 1; i <= lastdfa; ++i )
  417.         {
  418.         register int anum = dfaacc[i].dfaacc_state;
  419.  
  420.         mkdata( anum );
  421.  
  422.         if ( trace && anum )
  423.             fprintf( stderr, "state # %d accepts: [%d]\n",
  424.                 i, anum );
  425.         }
  426.  
  427.     dataend();
  428.  
  429.     if ( useecs )
  430.         genecs();
  431.  
  432.     /* Don't have to dump the actual full table entries - they were
  433.      * created on-the-fly.
  434.      */
  435.     }
  436.  
  437.  
  438. /* Generate the code to find the next compressed-table state. */
  439.  
  440. void gen_next_compressed_state( char_map )
  441. char *char_map;
  442.     {
  443.     indent_put2s( "register YY_CHAR yy_c = %s;", char_map );
  444.  
  445.     /* Save the backing-up info \before/ computing the next state
  446.      * because we always compute one more state than needed - we
  447.      * always proceed until we reach a jam state
  448.      */
  449.     gen_backing_up();
  450.  
  451.     indent_puts(
  452. "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
  453.     indent_up();
  454.     indent_puts( "{" );
  455.     indent_puts( "yy_current_state = (int) yy_def[yy_current_state];" );
  456.  
  457.     if ( usemecs )
  458.         {
  459.         /* We've arrange it so that templates are never chained
  460.          * to one another.  This means we can afford to make a
  461.          * very simple test to see if we need to convert to
  462.          * yy_c's meta-equivalence class without worrying
  463.          * about erroneously looking up the meta-equivalence
  464.          * class twice
  465.          */
  466.         do_indent();
  467.  
  468.         /* lastdfa + 2 is the beginning of the templates */
  469.         printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
  470.  
  471.         indent_up();
  472.         indent_puts( "yy_c = yy_meta[(unsigned int) yy_c];" );
  473.         indent_down();
  474.         }
  475.  
  476.     indent_puts( "}" );
  477.     indent_down();
  478.  
  479.     indent_puts(
  480. "yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];" );
  481.     }
  482.  
  483.  
  484. /* Generate the code to find the next match. */
  485.  
  486. void gen_next_match()
  487.     {
  488.     /* NOTE - changes in here should be reflected in gen_next_state() and
  489.      * gen_NUL_trans().
  490.      */
  491.     char *char_map = useecs ?
  492.                 "yy_ec[YY_SC_TO_UI(*yy_cp)]" :
  493.                 "YY_SC_TO_UI(*yy_cp)";
  494.  
  495.     char *char_map_2 = useecs ?
  496.                 "yy_ec[YY_SC_TO_UI(*++yy_cp)]" :
  497.                 "YY_SC_TO_UI(*++yy_cp)";
  498.  
  499.     if ( fulltbl )
  500.         {
  501.         indent_put2s(
  502.     "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
  503.                 char_map );
  504.  
  505.         indent_up();
  506.  
  507.         if ( num_backing_up > 0 )
  508.             {
  509.             indent_puts( "{" );    /* } for vi */
  510.             gen_backing_up();
  511.             putchar( '\n' );
  512.             }
  513.  
  514.         indent_puts( "++yy_cp;" );
  515.  
  516.         if ( num_backing_up > 0 )
  517.             /* { for vi */
  518.             indent_puts( "}" );
  519.  
  520.         indent_down();
  521.  
  522.         putchar( '\n' );
  523.         indent_puts( "yy_current_state = -yy_current_state;" );
  524.         }
  525.  
  526.     else if ( fullspd )
  527.         {
  528.         indent_puts( "{" );    /* } for vi */
  529.         indent_puts(
  530.         "register const struct yy_trans_info *yy_trans_info;\n" );
  531.         indent_puts( "register YY_CHAR yy_c;\n" );
  532.         indent_put2s( "for ( yy_c = %s;", char_map );
  533.         indent_puts(
  534.     "      (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->" );
  535.         indent_puts( "yy_verify == yy_c;" );
  536.         indent_put2s( "      yy_c = %s )", char_map_2 );
  537.  
  538.         indent_up();
  539.  
  540.         if ( num_backing_up > 0 )
  541.             indent_puts( "{" );    /* } for vi */
  542.  
  543.         indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  544.  
  545.         if ( num_backing_up > 0 )
  546.             {
  547.             putchar( '\n' );
  548.             gen_backing_up();    /* { for vi */
  549.             indent_puts( "}" );
  550.             }
  551.  
  552.         indent_down();    /* { for vi */
  553.         indent_puts( "}" );
  554.         }
  555.  
  556.     else
  557.         { /* compressed */
  558.         indent_puts( "do" );
  559.  
  560.         indent_up();
  561.         indent_puts( "{" );    /* } for vi */
  562.  
  563.         gen_next_state( false );
  564.  
  565.         indent_puts( "++yy_cp;" );
  566.  
  567.         /* { for vi */
  568.         indent_puts( "}" );
  569.         indent_down();
  570.  
  571.         do_indent();
  572.  
  573.         if ( interactive )
  574.             printf( "while ( yy_base[yy_current_state] != %d );\n",
  575.                 jambase );
  576.         else
  577.             printf( "while ( yy_current_state != %d );\n",
  578.                 jamstate );
  579.  
  580.         if ( ! reject && ! interactive )
  581.             {
  582.             /* Do the guaranteed-needed backing up to figure out
  583.              * the match.
  584.              */
  585.             indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  586.             indent_puts(
  587.                 "yy_current_state = yy_last_accepting_state;" );
  588.             }
  589.         }
  590.     }
  591.  
  592.  
  593. /* Generate the code to find the next state. */
  594.  
  595. void gen_next_state( worry_about_NULs )
  596. int worry_about_NULs;
  597.     { /* NOTE - changes in here should be reflected in get_next_match() */
  598.     char char_map[256];
  599.  
  600.     if ( worry_about_NULs && ! nultrans )
  601.         {
  602.         if ( useecs )
  603.             (void) sprintf( char_map,
  604.                 "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)",
  605.                     NUL_ec );
  606.         else
  607.             (void) sprintf( char_map,
  608.                 "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", NUL_ec );
  609.         }
  610.  
  611.     else
  612.         strcpy( char_map, useecs ? "yy_ec[YY_SC_TO_UI(*yy_cp)]" :
  613.                        "YY_SC_TO_UI(*yy_cp)" );
  614.  
  615.     if ( worry_about_NULs && nultrans )
  616.         {
  617.         if ( ! fulltbl && ! fullspd )
  618.             /* Compressed tables back up *before* they match. */
  619.             gen_backing_up();
  620.  
  621.         indent_puts( "if ( *yy_cp )" );
  622.         indent_up();
  623.         indent_puts( "{" );    /* } for vi */
  624.         }
  625.  
  626.     if ( fulltbl )
  627.         indent_put2s(
  628.             "yy_current_state = yy_nxt[yy_current_state][%s];", 
  629.                 char_map );
  630.  
  631.     else if ( fullspd )
  632.         indent_put2s(
  633.             "yy_current_state += yy_current_state[%s].yy_nxt;",
  634.                 char_map );
  635.  
  636.     else
  637.         gen_next_compressed_state( char_map );
  638.  
  639.     if ( worry_about_NULs && nultrans )
  640.         {
  641.         /* { for vi */
  642.         indent_puts( "}" );
  643.         indent_down();
  644.         indent_puts( "else" );
  645.         indent_up();
  646.         indent_puts(
  647.             "yy_current_state = yy_NUL_trans[yy_current_state];" );
  648.         indent_down();
  649.         }
  650.  
  651.     if ( fullspd || fulltbl )
  652.         gen_backing_up();
  653.  
  654.     if ( reject )
  655.         indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  656.     }
  657.  
  658.  
  659. /* Generate the code to make a NUL transition. */
  660.  
  661. void gen_NUL_trans()
  662.     { /* NOTE - changes in here should be reflected in get_next_match() */
  663.     int need_backing_up = (num_backing_up > 0 && ! reject);
  664.  
  665.     if ( need_backing_up )
  666.         /* We'll need yy_cp lying around for the gen_backing_up(). */
  667.         indent_puts( "register char *yy_cp = yy_c_buf_p;" );
  668.  
  669.     putchar( '\n' );
  670.  
  671.     if ( nultrans )
  672.         {
  673.         indent_puts(
  674.             "yy_current_state = yy_NUL_trans[yy_current_state];" );
  675.         indent_puts( "yy_is_jam = (yy_current_state == 0);" );
  676.         }
  677.  
  678.     else if ( fulltbl )
  679.         {
  680.         do_indent();
  681.         printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
  682.             NUL_ec );
  683.         indent_puts( "yy_is_jam = (yy_current_state <= 0);" );
  684.         }
  685.  
  686.     else if ( fullspd )
  687.         {
  688.         do_indent();
  689.         printf( "register int yy_c = %d;\n", NUL_ec );
  690.  
  691.         indent_puts(
  692.         "register const struct yy_trans_info *yy_trans_info;\n" );
  693.         indent_puts(
  694.         "yy_trans_info = &yy_current_state[(unsigned int) yy_c];" );
  695.         indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  696.  
  697.         indent_puts(
  698.             "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" );
  699.         }
  700.  
  701.     else
  702.         {
  703.         char NUL_ec_str[20];
  704.  
  705.         (void) sprintf( NUL_ec_str, "%d", NUL_ec );
  706.         gen_next_compressed_state( NUL_ec_str );
  707.  
  708.         if ( reject )
  709.             indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  710.  
  711.         do_indent();
  712.  
  713.         printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
  714.         }
  715.  
  716.     /* If we've entered an accepting state, back up; note that
  717.      * compressed tables have *already* done such backing up, so
  718.      * we needn't bother with it again.
  719.      */
  720.     if ( need_backing_up && (fullspd || fulltbl) )
  721.         {
  722.         putchar( '\n' );
  723.         indent_puts( "if ( ! yy_is_jam )" );
  724.         indent_up();
  725.         indent_puts( "{" );
  726.         gen_backing_up();
  727.         indent_puts( "}" );
  728.         indent_down();
  729.         }
  730.     }
  731.  
  732.  
  733. /* Generate the code to find the start state. */
  734.  
  735. void gen_start_state()
  736.     {
  737.     if ( fullspd )
  738.         indent_put2s(
  739.             "yy_current_state = yy_start_state_list[yy_start%s];",
  740.             bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );
  741.  
  742.     else
  743.         {
  744.         indent_puts( "yy_current_state = yy_start;" );
  745.  
  746.         if ( bol_needed )
  747.             {
  748.             indent_puts( "if ( yy_bp[-1] == '\\n' )" );
  749.             indent_up();
  750.             indent_puts( "++yy_current_state;" );
  751.             indent_down();
  752.             }
  753.  
  754.         if ( reject )
  755.             {
  756.             /* Set up for storing up states. */
  757.             indent_puts( "yy_state_ptr = yy_state_buf;" );
  758.             indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  759.             }
  760.         }
  761.     }
  762.  
  763.  
  764. /* gentabs - generate data statements for the transition tables */
  765.  
  766. void gentabs()
  767.     {
  768.     int i, j, k, *accset, nacc, *acc_array, total_states;
  769.     int end_of_buffer_action = num_rules + 1;
  770.  
  771.     acc_array = allocate_integer_array( current_max_dfas );
  772.     nummt = 0;
  773.  
  774.     /* The compressed table format jams by entering the "jam state",
  775.      * losing information about the previous state in the process.
  776.      * In order to recover the previous state, we effectively need
  777.      * to keep backing-up information.
  778.      */
  779.     ++num_backing_up;
  780.  
  781.     if ( reject )
  782.         {
  783.         /* Write out accepting list and pointer list.
  784.          *
  785.          * First we generate the "yy_acclist" array.  In the process,
  786.          * we compute the indices that will go into the "yy_accept"
  787.          * array, and save the indices in the dfaacc array.
  788.          */
  789.         int EOB_accepting_list[2];
  790.  
  791.         /* Set up accepting structures for the End Of Buffer state. */
  792.         EOB_accepting_list[0] = 0;
  793.         EOB_accepting_list[1] = end_of_buffer_action;
  794.         accsiz[end_of_buffer_state] = 1;
  795.         dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
  796.  
  797.         printf( long_align ? C_long_decl : C_short_decl,
  798.             "yy_acclist", MAX( numas, 1 ) + 1 );
  799.  
  800.         j = 1;    /* index into "yy_acclist" array */
  801.  
  802.         for ( i = 1; i <= lastdfa; ++i )
  803.             {
  804.             acc_array[i] = j;
  805.  
  806.             if ( accsiz[i] != 0 )
  807.                 {
  808.                 accset = dfaacc[i].dfaacc_set;
  809.                 nacc = accsiz[i];
  810.  
  811.                 if ( trace )
  812.                     fprintf( stderr,
  813.                         "state # %d accepts: ", i );
  814.  
  815.                 for ( k = 1; k <= nacc; ++k )
  816.                     {
  817.                     int accnum = accset[k];
  818.  
  819.                     ++j;
  820.  
  821.                     if ( variable_trailing_context_rules &&
  822.                       ! (accnum & YY_TRAILING_HEAD_MASK) &&
  823.                        accnum > 0 && accnum <= num_rules &&
  824.                       rule_type[accnum] == RULE_VARIABLE )
  825.                         {
  826.                         /* Special hack to flag
  827.                          * accepting number as part
  828.                          * of trailing context rule.
  829.                          */
  830.                         accnum |= YY_TRAILING_MASK;
  831.                         }
  832.  
  833.                     mkdata( accnum );
  834.  
  835.                     if ( trace )
  836.                         {
  837.                         fprintf( stderr, "[%d]",
  838.                             accset[k] );
  839.  
  840.                         if ( k < nacc )
  841.                             fputs( ", ", stderr );
  842.                         else
  843.                             putc( '\n', stderr );
  844.                         }
  845.                     }
  846.                 }
  847.             }
  848.  
  849.         /* add accepting number for the "jam" state */
  850.         acc_array[i] = j;
  851.  
  852.         dataend();
  853.         }
  854.  
  855.     else
  856.         {
  857.         dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  858.  
  859.         for ( i = 1; i <= lastdfa; ++i )
  860.             acc_array[i] = dfaacc[i].dfaacc_state;
  861.  
  862.         /* add accepting number for jam state */
  863.         acc_array[i] = 0;
  864.         }
  865.  
  866.     /* Spit out "yy_accept" array.  If we're doing "reject", it'll be
  867.      * pointers into the "yy_acclist" array.  Otherwise it's actual
  868.      * accepting numbers.  In either case, we just dump the numbers.
  869.      */
  870.  
  871.     /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
  872.      * beginning at 0 and for "jam" state.
  873.      */
  874.     k = lastdfa + 2;
  875.  
  876.     if ( reject )
  877.         /* We put a "cap" on the table associating lists of accepting
  878.          * numbers with state numbers.  This is needed because we tell
  879.          * where the end of an accepting list is by looking at where
  880.          * the list for the next state starts.
  881.          */
  882.         ++k;
  883.  
  884.     printf( long_align ? C_long_decl : C_short_decl, "yy_accept", k );
  885.  
  886.     for ( i = 1; i <= lastdfa; ++i )
  887.         {
  888.         mkdata( acc_array[i] );
  889.  
  890.         if ( ! reject && trace && acc_array[i] )
  891.             fprintf( stderr, "state # %d accepts: [%d]\n",
  892.                 i, acc_array[i] );
  893.         }
  894.  
  895.     /* Add entry for "jam" state. */
  896.     mkdata( acc_array[i] );
  897.  
  898.     if ( reject )
  899.         /* Add "cap" for the list. */
  900.         mkdata( acc_array[i] );
  901.  
  902.     dataend();
  903.  
  904.     if ( useecs )
  905.         genecs();
  906.  
  907.     if ( usemecs )
  908.         {
  909.         /* Write out meta-equivalence classes (used to index
  910.          * templates with).
  911.          */
  912.  
  913.         if ( trace )
  914.             fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
  915.  
  916.         printf( C_int_decl, "yy_meta", numecs + 1 );
  917.  
  918.         for ( i = 1; i <= numecs; ++i )
  919.             {
  920.             if ( trace )
  921.                 fprintf( stderr, "%d = %d\n",
  922.                     i, ABS( tecbck[i] ) );
  923.  
  924.             mkdata( ABS( tecbck[i] ) );
  925.             }
  926.  
  927.         dataend();
  928.         }
  929.  
  930.     total_states = lastdfa + numtemps;
  931.  
  932.     printf( (tblend >= MAX_SHORT || long_align) ?
  933.             C_long_decl : C_short_decl,
  934.         "yy_base", total_states + 1 );
  935.  
  936.     for ( i = 1; i <= lastdfa; ++i )
  937.         {
  938.         register int d = def[i];
  939.  
  940.         if ( base[i] == JAMSTATE )
  941.             base[i] = jambase;
  942.  
  943.         if ( d == JAMSTATE )
  944.             def[i] = jamstate;
  945.  
  946.         else if ( d < 0 )
  947.             {
  948.             /* Template reference. */
  949.             ++tmpuses;
  950.             def[i] = lastdfa - d + 1;
  951.             }
  952.  
  953.         mkdata( base[i] );
  954.         }
  955.  
  956.     /* Generate jam state's base index. */
  957.     mkdata( base[i] );
  958.  
  959.     for ( ++i /* skip jam state */; i <= total_states; ++i )
  960.         {
  961.         mkdata( base[i] );
  962.         def[i] = jamstate;
  963.         }
  964.  
  965.     dataend();
  966.  
  967.     printf( (total_states >= MAX_SHORT || long_align) ?
  968.             C_long_decl : C_short_decl,
  969.         "yy_def", total_states + 1 );
  970.  
  971.     for ( i = 1; i <= total_states; ++i )
  972.         mkdata( def[i] );
  973.  
  974.     dataend();
  975.  
  976.     printf( (total_states >= MAX_SHORT || long_align) ?
  977.             C_long_decl : C_short_decl,
  978.         "yy_nxt", tblend + 1 );
  979.  
  980.     for ( i = 1; i <= tblend; ++i )
  981.         {
  982.         if ( nxt[i] == 0 || chk[i] == 0 )
  983.             nxt[i] = jamstate;    /* new state is the JAM state */
  984.  
  985.         mkdata( nxt[i] );
  986.         }
  987.  
  988.     dataend();
  989.  
  990.     printf( (total_states >= MAX_SHORT || long_align) ?
  991.             C_long_decl : C_short_decl,
  992.         "yy_chk", tblend + 1 );
  993.  
  994.     for ( i = 1; i <= tblend; ++i )
  995.         {
  996.         if ( chk[i] == 0 )
  997.             ++nummt;
  998.  
  999.         mkdata( chk[i] );
  1000.         }
  1001.  
  1002.     dataend();
  1003.     }
  1004.  
  1005.  
  1006. /* Write out a formatted string (with a secondary string argument) at the
  1007.  * current indentation level, adding a final newline.
  1008.  */
  1009.  
  1010. void indent_put2s( fmt, arg )
  1011. char fmt[], arg[];
  1012.     {
  1013.     do_indent();
  1014.     printf( fmt, arg );
  1015.     putchar( '\n' );
  1016.     }
  1017.  
  1018.  
  1019. /* Write out a string at the current indentation level, adding a final
  1020.  * newline.
  1021.  */
  1022.  
  1023. void indent_puts( str )
  1024. char str[];
  1025.     {
  1026.     do_indent();
  1027.     puts( str );
  1028.     }
  1029.  
  1030.  
  1031. /* make_tables - generate transition tables and finishes generating output file
  1032.  */
  1033.  
  1034. void make_tables()
  1035.     {
  1036.     register int i;
  1037.     int did_eof_rule = false;
  1038.  
  1039.     skelout();
  1040.  
  1041.     /* First, take care of YY_DO_BEFORE_ACTION depending on yymore
  1042.      * being used.
  1043.      */
  1044.     set_indent( 1 );
  1045.  
  1046.     if ( yymore_used )
  1047.         {
  1048.         indent_puts( "yytext_ptr -= yy_more_len; \\" );
  1049.         indent_puts( "yyleng = yy_cp - yytext_ptr; \\" );
  1050.         }
  1051.  
  1052.     else
  1053.         indent_puts( "yyleng = yy_cp - yy_bp; \\" );
  1054.  
  1055.     /* Now also deal with copying yytext_ptr to yytext if needed. */
  1056.     skelout();
  1057.     if ( yytext_is_array )
  1058.         {
  1059.         indent_puts( "if ( yyleng >= YYLMAX ) \\" );
  1060.         indent_up();
  1061.         indent_puts(
  1062.         "YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\" );
  1063.         indent_down();
  1064.         indent_puts(
  1065.         "yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1 ); \\" );
  1066.         }
  1067.  
  1068.     set_indent( 0 );
  1069.  
  1070.     skelout();
  1071.  
  1072.  
  1073.     printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
  1074.  
  1075.     if ( fullspd )
  1076.         {
  1077.         /* Need to define the transet type as a size large
  1078.          * enough to hold the biggest offset.
  1079.          */
  1080.         int total_table_size = tblend + numecs + 1;
  1081.         char *trans_offset_type =
  1082.             (total_table_size >= MAX_SHORT || long_align) ?
  1083.                 "long" : "short";
  1084.  
  1085.         set_indent( 0 );
  1086.         indent_puts( "struct yy_trans_info" );
  1087.         indent_up();
  1088.         indent_puts( "{" );     /* } for vi */
  1089.  
  1090.         if ( long_align )
  1091.             indent_puts( "long yy_verify;" );
  1092.         else
  1093.             indent_puts( "short yy_verify;" );
  1094.  
  1095.         /* In cases where its sister yy_verify *is* a "yes, there is
  1096.          * a transition", yy_nxt is the offset (in records) to the
  1097.          * next state.  In most cases where there is no transition,
  1098.          * the value of yy_nxt is irrelevant.  If yy_nxt is the -1th
  1099.          * record of a state, though, then yy_nxt is the action number
  1100.          * for that state.
  1101.          */
  1102.  
  1103.         indent_put2s( "%s yy_nxt;", trans_offset_type );
  1104.         indent_puts( "};" );
  1105.         indent_down();
  1106.         }
  1107.  
  1108.     if ( fullspd )
  1109.         genctbl();
  1110.     else if ( fulltbl )
  1111.         genftbl();
  1112.     else
  1113.         gentabs();
  1114.  
  1115.     /* Definitions for backing up.  We don't need them if REJECT
  1116.      * is being used because then we use an alternative backin-up
  1117.      * technique instead.
  1118.      */
  1119.     if ( num_backing_up > 0 && ! reject )
  1120.         {
  1121.         if ( ! C_plus_plus )
  1122.             {
  1123.             indent_puts(
  1124.             "static yy_state_type yy_last_accepting_state;" );
  1125.             indent_puts(
  1126.                 "static char *yy_last_accepting_cpos;\n" );
  1127.             }
  1128.         }
  1129.  
  1130.     if ( nultrans )
  1131.         {
  1132.         printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 );
  1133.  
  1134.         for ( i = 1; i <= lastdfa; ++i )
  1135.             {
  1136.             if ( fullspd )
  1137.                 printf( "    &yy_transition[%d],\n", base[i] );
  1138.             else
  1139.                 mkdata( nultrans[i] );
  1140.             }
  1141.  
  1142.         dataend();
  1143.         }
  1144.  
  1145.     if ( ddebug )
  1146.         { /* Spit out table mapping rules to line numbers. */
  1147.         indent_puts( "extern int yy_flex_debug;" );
  1148.         indent_puts( "int yy_flex_debug = 1;\n" );
  1149.  
  1150.         printf( long_align ? C_long_decl : C_short_decl,
  1151.             "yy_rule_linenum", num_rules );
  1152.         for ( i = 1; i < num_rules; ++i )
  1153.             mkdata( rule_linenum[i] );
  1154.         dataend();
  1155.         }
  1156.  
  1157.     if ( reject )
  1158.         {
  1159.         /* Declare state buffer variables. */
  1160.         if ( ! C_plus_plus )
  1161.             {
  1162.             puts(
  1163.     "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
  1164.             puts( "static char *yy_full_match;" );
  1165.             puts( "static int yy_lp;" );
  1166.             }
  1167.  
  1168.         if ( variable_trailing_context_rules )
  1169.             {
  1170.             if ( ! C_plus_plus )
  1171.                 {
  1172.                 puts(
  1173.                 "static int yy_looking_for_trail_begin = 0;" );
  1174.                 puts( "static int yy_full_lp;" );
  1175.                 puts( "static int *yy_full_state;" );
  1176.                 }
  1177.  
  1178.             printf( "#define YY_TRAILING_MASK 0x%x\n",
  1179.                 (unsigned int) YY_TRAILING_MASK );
  1180.             printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
  1181.                 (unsigned int) YY_TRAILING_HEAD_MASK );
  1182.             }
  1183.  
  1184.         puts( "#define REJECT \\" );
  1185.         puts( "{ \\" );        /* } for vi */
  1186.         puts(
  1187.     "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
  1188.         puts(
  1189.     "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
  1190.  
  1191.         if ( variable_trailing_context_rules )
  1192.             {
  1193.             puts(
  1194.         "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
  1195.             puts(
  1196.         "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
  1197.             puts(
  1198.     "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
  1199.             }
  1200.  
  1201.         puts( "++yy_lp; \\" );
  1202.         puts( "goto find_rule; \\" );
  1203.         /* { for vi */
  1204.         puts( "}" );
  1205.         }
  1206.  
  1207.     else
  1208.         {
  1209.         puts(
  1210.         "/* The intent behind this definition is that it'll catch" );
  1211.         puts( " * any uses of REJECT which flex missed." );
  1212.         puts( " */" );
  1213.         puts( "#define REJECT reject_used_but_not_detected" );
  1214.         }
  1215.  
  1216.     if ( yymore_used )
  1217.         {
  1218.         if ( ! C_plus_plus )
  1219.             {
  1220.             indent_puts( "static int yy_more_flag = 0;" );
  1221.             indent_puts( "static int yy_more_len = 0;" );
  1222.             }
  1223.  
  1224.         indent_puts( "#define yymore() (yy_more_flag = 1)" );
  1225.         indent_puts( "#define YY_MORE_ADJ yy_more_len" );
  1226.         }
  1227.  
  1228.     else
  1229.         {
  1230.         indent_puts( "#define yymore() yymore_used_but_not_detected" );
  1231.         indent_puts( "#define YY_MORE_ADJ 0" );
  1232.         }
  1233.  
  1234.     if ( ! C_plus_plus )
  1235.         {
  1236.         if ( yytext_is_array )
  1237.             {
  1238.             puts( "#ifndef YYLMAX" );
  1239.             puts( "#define YYLMAX 8192" );
  1240.             puts( "#endif\n" );
  1241.             puts( "char yytext[YYLMAX];" );
  1242.             puts( "char *yytext_ptr;" );
  1243.             }
  1244.  
  1245.         else
  1246.             puts( "char *yytext;" );
  1247.         }
  1248.  
  1249.     fputs( &action_array[defs1_offset], stdout );
  1250.  
  1251.     skelout();
  1252.  
  1253.     if ( ! C_plus_plus )
  1254.         {
  1255.         if ( use_read )
  1256.             {
  1257.             printf(
  1258. "\tif ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\\n" );
  1259.             printf(
  1260.         "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );\n" );
  1261.             }
  1262.  
  1263.         else
  1264.             {
  1265.             printf(
  1266.             "\tif ( yy_current_buffer->yy_is_interactive ) \\\n" );
  1267.             printf( "\t\t{ \\\n" );
  1268.             printf( "\t\tint c = getc( yyin ); \\\n" );
  1269.             printf( "\t\tresult = c == EOF ? 0 : 1; \\\n" );
  1270.             printf( "\t\tbuf[0] = (char) c; \\\n" );
  1271.             printf( "\t\t} \\\n" );
  1272.             printf(
  1273.     "\telse if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\\n" );
  1274.             printf( "\t\t  && ferror( yyin ) ) \\\n" );
  1275.             printf(
  1276.         "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );\n" );
  1277.             }
  1278.         }
  1279.  
  1280.     skelout();
  1281.  
  1282.     /* Copy prolog to output file. */
  1283.     fputs( &action_array[prolog_offset], stdout );
  1284.  
  1285.     skelout();
  1286.  
  1287.     set_indent( 2 );
  1288.  
  1289.     if ( yymore_used )
  1290.         {
  1291.         indent_puts( "yy_more_len = 0;" );
  1292.         indent_puts( "if ( yy_more_flag )" );
  1293.         indent_up();
  1294.         indent_puts( "{" );
  1295.         indent_puts( "yy_more_len = yyleng;" );
  1296.         indent_puts( "yy_more_flag = 0;" );
  1297.         indent_puts( "}" );
  1298.         indent_down();
  1299.         }
  1300.  
  1301.     skelout();
  1302.  
  1303.     gen_start_state();
  1304.  
  1305.     /* Note, don't use any indentation. */
  1306.     puts( "yy_match:" );
  1307.     gen_next_match();
  1308.  
  1309.     skelout();
  1310.     set_indent( 2 );
  1311.     gen_find_action();
  1312.  
  1313.     skelout();
  1314.     if ( lex_compat )
  1315.         {
  1316.         indent_puts( "if ( yy_act != YY_END_OF_BUFFER )" );
  1317.         indent_up();
  1318.         indent_puts( "{" );
  1319.         indent_puts( "int yyl;" );
  1320.         indent_puts( "for ( yyl = 0; yyl < yyleng; ++yyl )" );
  1321.         indent_up();
  1322.         indent_puts( "if ( yytext[yyl] == '\\n' )" );
  1323.         indent_up();
  1324.         indent_puts( "++yylineno;" );
  1325.         indent_down();
  1326.         indent_down();
  1327.         indent_puts( "}" );
  1328.         indent_down();
  1329.         }
  1330.  
  1331.     skelout();
  1332.     if ( ddebug )
  1333.         {
  1334.         indent_puts( "if ( yy_flex_debug )" );
  1335.         indent_up();
  1336.  
  1337.         indent_puts( "{" );
  1338.         indent_puts( "if ( yy_act == 0 )" );
  1339.         indent_up();
  1340.         indent_puts(
  1341.             "fprintf( stderr, \"--scanner backing up\\n\" );" );
  1342.         indent_down();
  1343.  
  1344.         do_indent();
  1345.         printf( "else if ( yy_act < %d )\n", num_rules );
  1346.         indent_up();
  1347.         indent_puts(
  1348.     "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," );
  1349.         indent_puts( "         yy_rule_linenum[yy_act], yytext );" );
  1350.         indent_down();
  1351.  
  1352.         do_indent();
  1353.         printf( "else if ( yy_act == %d )\n", num_rules );
  1354.         indent_up();
  1355.         indent_puts(
  1356.     "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," );
  1357.         indent_puts( "         yytext );" );
  1358.         indent_down();
  1359.  
  1360.         do_indent();
  1361.         printf( "else if ( yy_act == %d )\n", num_rules + 1 );
  1362.         indent_up();
  1363.         indent_puts(
  1364.     "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" );
  1365.         indent_down();
  1366.  
  1367.         do_indent();
  1368.         printf( "else\n" );
  1369.         indent_up();
  1370.         indent_puts(
  1371.     "fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );" );
  1372.         indent_down();
  1373.  
  1374.         indent_puts( "}" );
  1375.         indent_down();
  1376.         }
  1377.  
  1378.     /* Copy actions to output file. */
  1379.     skelout();
  1380.     indent_up();
  1381.     gen_bu_action();
  1382.     fputs( &action_array[action_offset], stdout );
  1383.  
  1384.     /* generate cases for any missing EOF rules */
  1385.     for ( i = 1; i <= lastsc; ++i )
  1386.         if ( ! sceof[i] )
  1387.             {
  1388.             do_indent();
  1389.             printf( "case YY_STATE_EOF(%s):\n", scname[i] );
  1390.             did_eof_rule = true;
  1391.             }
  1392.  
  1393.     if ( did_eof_rule )
  1394.         {
  1395.         indent_up();
  1396.         indent_puts( "yyterminate();" );
  1397.         indent_down();
  1398.         }
  1399.  
  1400.  
  1401.     /* Generate code for handling NUL's, if needed. */
  1402.  
  1403.     /* First, deal with backing up and setting up yy_cp if the scanner
  1404.      * finds that it should JAM on the NUL.
  1405.      */
  1406.     skelout();
  1407.     set_indent( 7 );
  1408.  
  1409.     if ( fullspd || fulltbl )
  1410.         indent_puts( "yy_cp = yy_c_buf_p;" );
  1411.  
  1412.     else
  1413.         { /* compressed table */
  1414.         if ( ! reject && ! interactive )
  1415.             {
  1416.             /* Do the guaranteed-needed backing up to figure
  1417.              * out the match.
  1418.              */
  1419.             indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  1420.             indent_puts(
  1421.                 "yy_current_state = yy_last_accepting_state;" );
  1422.             }
  1423.  
  1424.         else
  1425.             /* Still need to initialize yy_cp, though
  1426.              * yy_current_state was set up by
  1427.              * yy_get_previous_state().
  1428.              */
  1429.             indent_puts( "yy_cp = yy_c_buf_p;" );
  1430.         }
  1431.  
  1432.  
  1433.     /* Generate code for yy_get_previous_state(). */
  1434.     set_indent( 1 );
  1435.     skelout();
  1436.  
  1437.     if ( bol_needed )
  1438.         indent_puts( "register char *yy_bp = yytext_ptr;\n" );
  1439.  
  1440.     gen_start_state();
  1441.  
  1442.     set_indent( 2 );
  1443.     skelout();
  1444.     gen_next_state( true );
  1445.  
  1446.     set_indent( 1 );
  1447.     skelout();
  1448.     gen_NUL_trans();
  1449.  
  1450.     skelout();
  1451.     if ( lex_compat )
  1452.         { /* update yylineno inside of unput() */
  1453.         indent_puts( "if ( c == '\\n' )" );
  1454.         indent_up();
  1455.         indent_puts( "--yylineno;" );
  1456.         indent_down();
  1457.         }
  1458.  
  1459.     skelout();
  1460.  
  1461.     /* Copy remainder of input to output. */
  1462.  
  1463.     line_directive_out( stdout );
  1464.  
  1465.     if ( sectnum == 3 )
  1466.         (void) flexscan(); /* copy remainder of input to output */
  1467.     }
  1468.